#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PyQt6.QtWidgets import (
    QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
    QFileDialog, QLabel, QMessageBox, QSplitter, QTableWidget,
    QTableWidgetItem, QHeaderView, QListWidget, QListWidgetItem,
    QAbstractItemView, QFrame, QSpinBox, QStatusBar
)
from PyQt6.QtCore import Qt, QMimeData, QSize
from PyQt6.QtGui import QDrag, QColor, QFont, QAction
import pandas as pd
import os
import json
from datetime import datetime

from src.core.scheduler import Scheduler
from src.ui.widgets import ClassCell, ScheduleTable, DraggableListWidget

class MainWindow(QMainWindow):
    """Main application window for the Physical Education Scheduler."""
    
    def __init__(self):
        super().__init__()
        self.setWindowTitle("体育课程安排系统")
        self.setGeometry(100, 100, 1400, 800)
        
        # Initialize data storage
        self.student_data = None
        self.max_students_per_day = 8000
        self.schedule_table = None
        self.daily_stats = {}
        self.all_classes = []
        self.unscheduled_classes = []
        self.time_slots = ['第1-2节', '第3-4节', '第5-6节']
        self.days = ['星期一', '星期二', '星期三', '星期四', '星期五']
        
        self.init_ui()
    
    def init_ui(self):
        """Initialize the user interface with system theme support and compact layout."""
        # Create main widget and layout first
        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        main_layout = QVBoxLayout(main_widget)
        main_layout.setContentsMargins(8, 8, 8, 8)
        main_layout.setSpacing(6)

        # Create compact top controls
        controls_layout = QHBoxLayout()
        controls_layout.setSpacing(6)

        # Control buttons
        btn_style = """
            QPushButton {
                padding: 4px 8px;
                min-width: 80px;
                border: 1px solid palette(mid);
                border-radius: 4px;
            }
            QPushButton:hover {
                background: palette(light);
            }
        """
        
        self.import_btn = QPushButton("导入数据")
        self.import_btn.setStyleSheet(btn_style)
        
        self.template_btn = QPushButton("下载模板")
        self.template_btn.setStyleSheet(btn_style)
        
        self.auto_schedule_btn = QPushButton("自动排课")
        self.auto_schedule_btn.setStyleSheet(btn_style)
        
        self.clear_btn = QPushButton("清空课表")
        self.clear_btn.setStyleSheet(btn_style)

        # Add buttons to layout
        controls_layout.addWidget(self.import_btn)
        controls_layout.addWidget(self.template_btn)
        controls_layout.addWidget(self.auto_schedule_btn)
        controls_layout.addWidget(self.clear_btn)

        # Add stretch before max students control
        controls_layout.addStretch()
        
        # Max students control
        max_students_layout = QHBoxLayout()
        max_students_layout.setSpacing(4)
        
        max_students_label = QLabel("每日最大学生数:")
        self.max_students_spin = QSpinBox()
        self.max_students_spin.setRange(100, 20000)
        self.max_students_spin.setValue(self.max_students_per_day)
        self.max_students_spin.setFixedWidth(100)
        
        max_students_layout.addWidget(max_students_label)
        max_students_layout.addWidget(self.max_students_spin)
        controls_layout.addLayout(max_students_layout)

        # Add controls to main layout
        main_layout.addLayout(controls_layout)

        # Stats label at the bottom with some padding
        stats_container = QWidget()
        stats_layout = QVBoxLayout(stats_container)
        stats_layout.setContentsMargins(8, 4, 8, 4)
        
        self.stats_label = QLabel("")
        self.stats_label.setAlignment(Qt.AlignmentFlag.AlignLeft)
        self.stats_label.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse)
        
        # Add a subtle frame around the stats
        stats_container.setStyleSheet("""
            QWidget {
                border: 1px solid palette(mid);
                border-radius: 4px;
                padding: 4px;
                background: palette(window);
            }
        """)
        
        stats_layout.addWidget(self.stats_label)
        main_layout.addWidget(stats_container)

        # Create splitter for the main content
        splitter = QSplitter(Qt.Orientation.Horizontal)
        splitter.setHandleWidth(1)
        splitter.setStyleSheet("""
            QSplitter::handle {
                background: palette(mid);
            }
        """)

        # Left panel - Unscheduled classes
        left_panel = QWidget()
        left_layout = QVBoxLayout(left_panel)
        left_layout.setContentsMargins(0, 0, 0, 0)
        left_layout.setSpacing(4)

        unscheduled_label = QLabel("未安排课程")
        unscheduled_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        unscheduled_label.setStyleSheet("""
            font-weight: bold;
            padding: 3px;
            border-bottom: 1px solid palette(mid);
        """)
        left_layout.addWidget(unscheduled_label)

        self.unscheduled_list = DraggableListWidget()
        self.unscheduled_list.setDragDropMode(QAbstractItemView.DragDropMode.DragOnly)
        self.unscheduled_list.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
        self.unscheduled_list.setStyleSheet("""
            QListWidget {
                border: 1px solid palette(mid);
                border-radius: 4px;
                background-color: palette(base);
                font-size: 12px;
            }
            QListWidget::item {
                padding: 6px;
                border-bottom: 1px solid palette(light);
            }
            QListWidget::item:selected {
                background: palette(highlight);
                color: palette(highlighted-text);
            }
        """)
        left_layout.addWidget(self.unscheduled_list)

        # Right panel - Schedule table
        right_panel = QWidget()
        right_layout = QVBoxLayout(right_panel)
        right_layout.setContentsMargins(0, 0, 0, 0)
        right_layout.setSpacing(4)

        schedule_label = QLabel("课程表")
        schedule_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        schedule_label.setStyleSheet("""
            font-weight: bold;
            padding: 3px;
            border-bottom: 1px solid palette(mid);
        """)
        right_layout.addWidget(schedule_label)

        # Create a container widget for the schedule table with proper sizing
        table_container = QWidget()
        table_layout = QVBoxLayout(table_container)
        table_layout.setContentsMargins(0, 0, 0, 0)
        table_layout.setSpacing(0)
        
        # Initialize the schedule table
        self.schedule_table = ScheduleTable()
        table_layout.addWidget(self.schedule_table)
        
        # Add the container to the right layout
        right_layout.addWidget(table_container, 1)  # Add stretch factor to make it expand
        
        # Connect schedule changed signal to update statistics
        self.schedule_table.schedule_changed.connect(self.update_statistics)
        
        # Now set up the theme which will style the table
        self.setup_theme()

        # Add panels to splitter
        splitter.addWidget(left_panel)
        splitter.addWidget(right_panel)
        
        # Set stretch factors (1:3 ratio)
        splitter.setStretchFactor(0, 1)
        splitter.setStretchFactor(1, 3)

        # Add splitter to main layout
        main_layout.addWidget(splitter, 1)  # Add stretch factor to make it take remaining space

        # Status bar
        self.statusBar = QStatusBar()
        self.statusBar.setStyleSheet("""
            QStatusBar {
                border-top: 1px solid palette(mid);
            }
        """)
        self.setStatusBar(self.statusBar)
        self.statusBar.showMessage("就绪")

        # Set window properties
        self.setMinimumSize(900, 600)  # Slightly smaller minimum size
        self.setWindowTitle("体育课程安排系统")

        # Connect signals
        self.import_btn.clicked.connect(self.import_excel)
        self.template_btn.clicked.connect(self.download_template)
        self.auto_schedule_btn.clicked.connect(self.auto_schedule)
        self.clear_btn.clicked.connect(self.clear_schedule_with_confirm)
        self.max_students_spin.valueChanged.connect(self.update_max_students)

        # Update UI
        self.update_ui()

    def setup_theme(self):
        """Set up the application theme based on system settings."""
        # Use system palette for better theme support
        palette = self.palette()
        if self.is_dark_theme():
            # Dark theme colors
            palette.setColor(palette.ColorRole.Window, QColor(53, 53, 53))
            palette.setColor(palette.ColorRole.WindowText, QColor(255, 255, 255))
            palette.setColor(palette.ColorRole.Base, QColor(42, 42, 42))
            palette.setColor(palette.ColorRole.AlternateBase, QColor(53, 53, 53))
            palette.setColor(palette.ColorRole.ToolTipBase, QColor(255, 255, 255))
            palette.setColor(palette.ColorRole.ToolTipText, QColor(255, 255, 255))
            palette.setColor(palette.ColorRole.Text, QColor(255, 255, 255))
            palette.setColor(palette.ColorRole.Button, QColor(53, 53, 53))
            palette.setColor(palette.ColorRole.ButtonText, QColor(255, 255, 255))
            palette.setColor(palette.ColorRole.BrightText, QColor(255, 0, 0))
            palette.setColor(palette.ColorRole.Link, QColor(100, 160, 255))
            palette.setColor(palette.ColorRole.Highlight, QColor(42, 130, 218))
            palette.setColor(palette.ColorRole.HighlightedText, QColor(255, 255, 255))
        else:
            # Light theme colors
            palette.setColor(palette.ColorRole.Window, QColor(240, 240, 240))
            palette.setColor(palette.ColorRole.WindowText, QColor(0, 0, 0))
            palette.setColor(palette.ColorRole.Base, QColor(255, 255, 255))
            palette.setColor(palette.ColorRole.AlternateBase, QColor(240, 240, 240))
            palette.setColor(palette.ColorRole.ToolTipBase, QColor(255, 255, 255))
            palette.setColor(palette.ColorRole.ToolTipText, QColor(0, 0, 0))
            palette.setColor(palette.ColorRole.Text, QColor(0, 0, 0))
            palette.setColor(palette.ColorRole.Button, QColor(240, 240, 240))
            palette.setColor(palette.ColorRole.ButtonText, QColor(0, 0, 0))
            palette.setColor(palette.ColorRole.BrightText, QColor(255, 0, 0))
            palette.setColor(palette.ColorRole.Link, QColor(0, 102, 204))
            palette.setColor(palette.ColorRole.Highlight, QColor(0, 120, 215))
            palette.setColor(palette.ColorRole.HighlightedText, QColor(255, 255, 255))
        
        self.setPalette(palette)
        
        # Only update the schedule table if it exists
        if hasattr(self, 'schedule_table') and self.schedule_table is not None:
            self.update_schedule_table_style()
    
    def update_schedule_table_style(self):
        """Update the schedule table style based on the current theme."""
        if not hasattr(self, 'schedule_table') or self.schedule_table is None:
            return
            
        is_dark = self.is_dark_theme()
        
        # Base colors
        bg_color = self.palette().color(self.palette().ColorRole.Base)
        text_color = self.palette().color(self.palette().ColorRole.Text)
        highlight_color = self.palette().color(self.palette().ColorRole.Highlight)
        highlight_text_color = self.palette().color(self.palette().ColorRole.HighlightedText)
        button_color = self.palette().color(self.palette().ColorRole.Button)
        button_text_color = self.palette().color(self.palette().ColorRole.ButtonText)
        
        # Adjust colors for better contrast
        if is_dark:
            header_bg = button_color.darker(120)
            header_text = button_text_color
            cell_border = button_color.darker(150)
            cell_hover = button_color.lighter(120)
        else:
            header_bg = button_color.lighter(105)
            header_text = button_text_color
            cell_border = button_color.darker(110)
            cell_hover = button_color.darker(105)
        
        # Apply styles to the schedule table
        self.schedule_table.setStyleSheet(f"""
            QTableWidget {{
                background-color: {bg_color.name()};
                color: {text_color.name()};
                gridline-color: {cell_border.name()};
                border: 1px solid {cell_border.name()};
                border-radius: 4px;
            }}
            QTableWidget::item {{
                padding: 4px;
                border: 1px solid {cell_border.name()};
            }}
            QTableWidget::item:selected {{
                background-color: {highlight_color.name()};
                color: {highlight_text_color.name()};
            }}
            QTableWidget::item:hover {{
                background-color: {cell_hover.name()};
            }}
            QHeaderView::section {{
                background-color: {header_bg.name()};
                color: {header_text.name()};
                padding: 4px;
                border: 1px solid {cell_border.name()};
                font-weight: bold;
            }}
            QTableCornerButton::section {{
                background-color: {header_bg.name()};
                border: 1px solid {cell_border.name()};
            }}
        """)
        
        # Update the class cells in the table
        for row in range(self.schedule_table.rowCount()):
            for col in range(self.schedule_table.columnCount()):
                item = self.schedule_table.item(row, col)
                if hasattr(item, 'widgets'):
                    for widget in item.widgets:
                        if hasattr(widget, 'update_theme'):
                            widget.update_theme(is_dark)

    def is_dark_theme(self):
        """Check if the system is using a dark theme."""
        # Check system palette brightness
        palette = self.palette()
        background = palette.color(palette.ColorRole.Window)
        color = background.red() * 0.299 + background.green() * 0.587 + background.blue() * 0.114
        return color < 128
    
    def update_ui(self):
        """Update the UI elements based on current data."""
        self.update_unscheduled_list()
        self.update_statistics()
    
    def update_unscheduled_list(self):
        """Update the unscheduled classes list based on current schedule."""
        # Get all currently scheduled classes
        scheduled_classes = set()
        for row in range(self.schedule_table.rowCount()):
            for col in range(self.schedule_table.columnCount()):
                item = self.schedule_table.item(row, col)
                if item and hasattr(item, 'classes'):
                    for cls in item.classes:
                        key = (str(cls.get('college', '')), 
                              str(cls.get('major', '')), 
                              str(cls.get('grade', '')))
                        scheduled_classes.add(key)
        
        # Clear and rebuild the unscheduled list
        self.unscheduled_list.clear()
        
        # Update unscheduled_classes to only include classes not in the schedule
        self.unscheduled_classes = []
        
        # Only show classes that are not in the schedule
        for class_info in self.all_classes:
            key = (str(class_info.get('college', '')), 
                  str(class_info.get('major', '')), 
                  str(class_info.get('grade', '')))
            if key not in scheduled_classes:
                self.unscheduled_classes.append(class_info)
                
        # Sort the unscheduled classes
        self.unscheduled_classes.sort(key=lambda x: (x.get('college', ''), 
                                                    x.get('major', ''), 
                                                    x.get('grade', '')))
        
        # Update the list widget
        for class_info in self.unscheduled_classes:
            item = QListWidgetItem(self.format_class_info(class_info))
            item.setData(Qt.ItemDataRole.UserRole, class_info)
            self.unscheduled_list.addItem(item)
    
    def calculate_daily_stats(self):
        """Calculate daily statistics for students."""
        # Initialize daily stats
        daily_stats = {day: {'total': 0, 'male': 0, 'female': 0} for day in self.days}
        
        # Get scheduled classes from the table
        for row in range(self.schedule_table.rowCount()):
            for col in range(self.schedule_table.columnCount()):
                item = self.schedule_table.item(row, col)
                if item and hasattr(item, 'widgets') and item.widgets:
                    for widget in item.widgets:
                        if hasattr(widget, 'class_info'):
                            day = self.days[col]
                            # Get the class info from the widget
                            class_info = widget.class_info
                            # Calculate male and female counts
                            male = int(class_info.get('male', 0)) if str(class_info.get('male', '0')).isdigit() else 0
                            female = int(class_info.get('female', 0)) if str(class_info.get('female', '0')).isdigit() else 0
                            total = male + female
                            
                            # Update daily stats
                            daily_stats[day]['total'] += total
                            daily_stats[day]['male'] += male
                            daily_stats[day]['female'] += female
        
        return daily_stats
    
    def update_statistics(self):
        """Update the statistics display with theme-appropriate colors."""
        if self.student_data is not None:
            total_students = len(self.student_data)
            total_male = self.student_data['男生人数'].sum()
            total_female = self.student_data['女生人数'].sum()
            scheduled = len(self.all_classes) - len(self.unscheduled_classes)
            
            # Calculate daily statistics
            daily_stats = self.calculate_daily_stats()
            
            # Get text color based on current theme
            text_color = self.palette().color(self.palette().ColorRole.WindowText).name()
            
            # Create daily stats HTML
            daily_stats_html = []
            for day in self.days:
                stats = daily_stats[day]
                daily_stats_html.append(
                    f"<b>{day}:</b> 总{stats['total']}人 "
                    f"(男{stats['male']}/女{stats['female']})"
                )
            
            stats_text = (
                f"<div style='color: {text_color}'>"
                f"<div style='margin-bottom: 4px;'>"
                f"总学生: <b>{total_students}</b> | "
                f"男生: <b>{total_male}</b> | "
                f"女生: <b>{total_female}</b> | "
                f"已安排: <b>{scheduled}/{len(self.all_classes)}</b>"
                "</div>"
                f"<div style='font-size: 0.9em;'>{' | '.join(daily_stats_html)}</div>"
                "</div>"
            )
            
            self.stats_label.setTextFormat(Qt.TextFormat.RichText)
            self.stats_label.setWordWrap(True)
            self.stats_label.setText(stats_text)
    
    def import_excel(self):
        """Import student data from Excel file."""
        file_name, _ = QFileDialog.getOpenFileName(
            self, "选择Excel文件", "", "Excel 文件 (*.xlsx *.xls)")
            
        if file_name:
            try:
                # Read Excel file
                df = pd.read_excel(file_name)
                
                # Check required columns
                required_columns = ['学院', '专业', '年级', '男生人数', '女生人数']
                if not all(col in df.columns for col in required_columns):
                    QMessageBox.critical(
                        self,
                        "错误",
                        "Excel文件必须包含以下列: " + ", ".join(required_columns)
                    )
                    return
                
                # Store the data
                self.student_data = df
                
                # Process the data
                self.process_imported_data()
                
                # Update UI
                self.update_ui()
                
                self.statusBar.showMessage(f"成功导入 {len(df)} 条记录", 5000)
                
            except Exception as e:
                QMessageBox.critical(self, "导入错误", f"导入Excel文件时出错: {str(e)}")
    
    def process_imported_data(self):
        """Process the imported student data."""
        if self.student_data is not None:
            # Group by college, major, and grade
            grouped = self.student_data.groupby(['学院', '专业', '年级'])
            
            # Clear existing data
            self.all_classes = []
            self.unscheduled_classes = []
            
            # Create class entries
            for (college, major, grade), group in grouped:
                class_info = {
                    'college': college,
                    'major': major,
                    'grade': grade,
                    'male': int(group['男生人数'].sum()),
                    'female': int(group['女生人数'].sum()),
                    'total': int(group['男生人数'].sum() + group['女生人数'].sum())
                }
                
                # Add to all classes and unscheduled list
                self.all_classes.append(class_info)
                self.unscheduled_classes.append(class_info)
            
            # Sort classes by college, major, and grade
            self.all_classes.sort(key=lambda x: (x['college'], x['major'], x['grade']))
            self.unscheduled_classes.sort(key=lambda x: (x['college'], x['major'], x['grade']))
    
    def download_template(self):
        """Download the Excel template file."""
        try:
            # Create a sample template
            template_data = {
                '学院': ['计算机学院', '计算机学院', '经管学院'],
                '专业': ['计算机科学与技术', '软件工程', '工商管理'],
                '年级': [2022, 2022, 2023],
                '班级': ['1班', '2班', '1班'],
                '男生人数': [30, 25, 20],
                '女生人数': [20, 15, 30]
            }
            
            df = pd.DataFrame(template_data)
            
            # Get save file path
            file_name, _ = QFileDialog.getSaveFileName(
                self,
                "保存模板文件",
                "体育课程安排模板.xlsx",
                "Excel 文件 (*.xlsx)"
            )
            
            if file_name:
                # Ensure the file has .xlsx extension
                if not file_name.endswith('.xlsx'):
                    file_name += '.xlsx'
                
                df.to_excel(file_name, index=False)
                self.statusBar.showMessage(f"模板已保存到: {file_name}", 5000)
                
        except Exception as e:
            QMessageBox.critical(self, "错误", f"保存模板文件时出错: {str(e)}")
    
    def auto_schedule(self):
        """Automatically schedule classes."""
        if not self.unscheduled_classes:
            QMessageBox.information(self, "提示", "没有需要安排的课程")
            return
            
        try:
            # Create a scheduler instance
            scheduler = Scheduler(
                max_students_per_day=self.max_students_per_day,
                time_slots=self.time_slots,
                days=self.days
            )
            
            # Schedule the classes
            success, message = scheduler.auto_schedule(
                self.unscheduled_classes,
                self.schedule_table,
                self
            )
            
            if success:
                # Update unscheduled classes
                self.unscheduled_classes = [
                    cls for cls in self.all_classes 
                    if not any(
                        cls == scheduled 
                        for scheduled in scheduler.get_scheduled_classes()
                    )
                ]
                
                # Update UI
                self.update_ui()
                self.statusBar.showMessage(message, 5000)
            else:
                QMessageBox.warning(self, "排课警告", message)
                
        except Exception as e:
            QMessageBox.critical(self, "排课错误", f"自动排课时出错: {str(e)}")
    
    def clear_schedule_with_confirm(self):
        """Show confirmation dialog before clearing the schedule."""
        if not self.all_classes:
            return
            
        reply = QMessageBox.question(
            self,
            '确认清空',
            '确定要清空所有课程安排吗？此操作不可撤销。',
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
            QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            self.clear_schedule_and_reset()
    
    def clear_schedule_and_reset(self):
        """Clear the schedule and reset all data."""
        try:
            # Clear the schedule table
            if self.schedule_table:
                for row in range(self.schedule_table.rowCount()):
                    for col in range(self.schedule_table.columnCount()):
                        item = self.schedule_table.item(row, col)
                        if item and hasattr(item, 'classes'):
                            item.classes = []
                            self.schedule_table.update_cell_widgets(row, col)
            
            # Reset the unscheduled classes to all classes
            self.unscheduled_classes = [cls.copy() for cls in self.all_classes]
            
            # Update the unscheduled list
            self.update_unscheduled_list()
            
            # Update statistics and UI
            self.update_statistics()
            
            # Force update the UI
            self.schedule_table.viewport().update()
            self.unscheduled_list.viewport().update()
            
            # Emit schedule changed signal
            if self.schedule_table:
                self.schedule_table.schedule_changed.emit()
                
            self.statusBar.showMessage("已清空所有课程安排", 5000)
        except Exception as e:
            QMessageBox.critical(self, "错误", f"清空课表时出错: {str(e)}")
    
    def handle_class_drop(self, class_info_text, row, col):
        """Handle class drop event from unscheduled list to schedule."""
        try:
            # Find the class info in unscheduled classes
            class_info = None
            for cls in self.unscheduled_classes:
                if self.format_class_info(cls) == class_info_text:
                    class_info = cls
                    break
            
            if not class_info:
                return
                
            # Create a deep copy of the class info to avoid reference issues
            class_info_copy = class_info.copy()
            
            # Check if this class is already scheduled elsewhere
            for r in range(self.schedule_table.rowCount()):
                for c in range(self.schedule_table.columnCount()):
                    item = self.schedule_table.item(r, c)
                    if item and hasattr(item, 'classes'):
                        for scheduled_class in item.classes:
                            if (str(scheduled_class.get('college', '')) == str(class_info_copy.get('college', '')) and 
                                str(scheduled_class.get('major', '')) == str(class_info_copy.get('major', '')) and 
                                str(scheduled_class.get('grade', '')) == str(class_info_copy.get('grade', ''))):
                                QMessageBox.warning(
                                    self, 
                                    "排课冲突", 
                                    f"{class_info_copy.get('college', '')} {class_info_copy.get('major', '')} {class_info_copy.get('grade', '')}级 已经安排在{self.days[c]} {self.time_slots[r]}"
                                )
                                return
            
            # Add to schedule
            if self.schedule_table.add_class_to_cell(row, col, class_info_copy):
                # Remove the class from unscheduled_classes list
                self.unscheduled_classes = [
                    cls for cls in self.unscheduled_classes 
                    if not (str(cls.get('college', '')) == str(class_info_copy.get('college', '')) and 
                           str(cls.get('major', '')) == str(class_info_copy.get('major', '')) and 
                           str(cls.get('grade', '')) == str(class_info_copy.get('grade', '')))
                ]
                
                # Update the unscheduled list UI
                self.unscheduled_list.clear()
                for cls in self.unscheduled_classes:
                    item = QListWidgetItem(self.format_class_info(cls))
                    item.setData(Qt.ItemDataRole.UserRole, cls)
                    self.unscheduled_list.addItem(item)
                
                # Update statistics and UI
                self.update_statistics()
                self.statusBar.showMessage("课程已添加", 3000)
                
                # Emit schedule changed signal
                self.schedule_table.schedule_changed.emit()
                
                # Force update the UI
                self.schedule_table.viewport().update()
                self.unscheduled_list.viewport().update()
        except Exception as e:
            QMessageBox.critical(self, "错误", f"添加课程时出错: {str(e)}")
    
    def handle_class_move(self, class_info, source_pos, target_row, target_col):
        """Handle class move between cells in the schedule."""
        try:
            source_row, source_col = source_pos
            
            # Remove from source
            if self.schedule_table.remove_class_from_cell(source_row, source_col, class_info):
                # Add to target
                if self.schedule_table.add_class_to_cell(target_row, target_col, class_info):
                    self.statusBar.showMessage("课程已移动", 3000)
                    return
            
            # If we get here, something went wrong
            self.update_ui()
            QMessageBox.warning(self, "移动失败", "无法移动课程到目标位置")
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"移动课程时出错: {str(e)}")
    
    def handle_class_return(self, class_info_text):
        """Handle class return to unscheduled list."""
        try:
            # Find the class in the schedule and remove it
            for row in range(self.schedule_table.rowCount()):
                for col in range(self.schedule_table.columnCount()):
                    cell = self.schedule_table.item(row, col)
                    if cell and hasattr(cell, 'classes'):
                        # Make a copy of the list to avoid modifying it while iterating
                        for cls in cell.classes[:]:
                            if self.format_class_info(cls) == class_info_text:
                                # Remove from schedule
                                cell.classes.remove(cls)
                                self.schedule_table.update_cell_widgets(row, col)
                                
                                # Update the unscheduled list
                                self.update_unscheduled_list()
                                
                                # Update statistics and UI
                                self.update_statistics()
                                self.statusBar.showMessage("课程已返回未安排列表", 3000)
                                
                                # Force update the UI
                                self.schedule_table.viewport().update()
                                self.unscheduled_list.viewport().update()
                                return
        except Exception as e:
            QMessageBox.critical(self, "错误", f"返回课程时出错: {str(e)}")
    
    def update_max_students(self, value):
        """Update the maximum number of students per day."""
        self.max_students_per_day = value
    
    def format_class_info(self, class_data):
        """Format class information for display."""
        if isinstance(class_data, str):
            return class_data
            
        return f"{class_data['college']} {class_data['major']} {class_data['grade']}级\n男生: {class_data.get('male', 0)} 女生: {class_data.get('female', 0)}"

    def closeEvent(self, event):
        """Handle window close event."""
        if self.unscheduled_classes:
            reply = QMessageBox.question(
                self,
                '确认退出',
                '还有未安排的课程，确定要退出吗？',
                QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
                QMessageBox.StandardButton.No
            )
            
            if reply == QMessageBox.StandardButton.No:
                event.ignore()
                return
        
        event.accept()
